package com.pijunn.report

import com.pijunn.label.LabeledItem;
import com.pijunn.users.AppUser;

class LostController {

	/**
	 * Dependency injection for the springSecurityService.
	 */
	def springSecurityService
	
	def labelService

	def index() {
        redirect(action: "list", params: params)
    }

    def list(Integer max) {
        params.max = Math.min(max ?: 10, 100)
		AppUser user = springSecurityService.currentUser
		def admin = principal.authorities*.authority.contains("ROLE_ADMIN")

		def list = admin ? LabeledItem.list(params) : labelService.getMyItems()
		def count = admin ? LabeledItem.count() : labelService.getMyItems().size()
		
		log.info '*** List size: ' + count
		
        [cmd: new LostEventCommand(labeledItemInstanceList: list, labeledItemInstanceTotal: count, wizardStep:'select')]
    }
	
	def show(Integer id) {
		def item = LabeledItem.get(id)
		render view:'/lost/report', model: [cmd: new LostEventCommand(itemId: [id], description: item.description, wizardStep:'confirm')]
		
	}
	
	def report(LostEventCommand cmd) {
		if (cmd.previous) {
			reportPrevious(cmd)
			return
		}
		
		if(cmd.hasErrors()) {
			render view:cmd.wizardStep == 'select' ? '/lost/list' : 'report', model: [cmd: cmd]
			return
		}
		
		def event = cmd.eventId ? LostEvent.get(cmd.eventId) : new LostEvent(item: LabeledItem.get(Integer.valueOf(cmd.itemId[0])))
		
		switch(cmd.wizardStep) {
			case 'select':
			// Has someone already found it?
				def labeledItem = LabeledItem.get(cmd.itemId[0])
				def found = FoundEvent.withCriteria() {
					isNull("handlingAmount")
					item { 
						eq("id", labeledItem.id)
					}
				}

				if (found.size() > 0) {
					cmd.foundTime = new Date()
					return [cmd: cmd, item: labeledItem, event: found]
				}
				
				cmd.description = labeledItem?.description
				cmd.lost = cmd.lost ?: event.lostTime ? cmd.fmt.format(event.lostTime) : ''
				cmd.location = cmd.location ?: event.track[0]?.location
				cmd.venue = cmd.venue ?: event.track[0]?.venue

				cmd.wizardStep = 'confirm'
				break;
			case 'confirm':
				// Create 'bare' LostEvent
				event.item = LabeledItem.get(cmd.itemId[0])
				event.description = cmd.description
				event.lostTime = cmd.lostDate
				if (!event.track || event.track.size() == 0) {
					TrackBack track = new TrackBack(location: cmd.location, venue: cmd.venue, event: event)
					event.addToTrack(track)
				}
				event.save()
				
				if (event.hasErrors()) {
					cmd.errors = event.errors
					return [cmd: cmd, item: event.item, event: event]
				}
				
				
				cmd.eventId = event.id
				prepareTracking(cmd, event)
				cmd.wizardStep = 'trackback'
				break;
			case 'trackback':
				if (cmd.trackingDeleteId) {
					def tb = TrackBack.get(cmd.trackingDeleteId)
					event.removeFromTrack(tb)
					event.save()
					tb.delete(flush:true)
					prepareTracking(cmd, event)
					return [cmd: cmd]
				}
				
				for (def i = 0; i < cmd.trackingVenue.size(); i++) {
					if (cmd.trackingVenue[i] && cmd.trackingLocation[i]) {
						TrackBack trackBack = cmd.trackingId[i] ? TrackBack.get(Integer.valueOf(cmd.trackingId[i])) : new TrackBack(venue: cmd.trackingVenue[i], location: cmd.trackingLocation[i], room: cmd.trackingRoom[i])
						trackBack.event = event
						trackBack.location = cmd.trackingLocation[i]
						trackBack.venue = cmd.trackingVenue[i]
						trackBack.room = cmd.trackingRoom[i]
						if (!trackBack.id)
							event.addToTrack(trackBack)
						else
							trackBack.save()
					}
				}

				def user = springSecurityService.getCurrentUser()
				cmd.contact = event.contact ?: new Contact(name: user.firstName + ' ' + user.lastName, email: user.contactEMail, skypeId: user.contactSkypeId)
				cmd.mailing = event.contact?.mailingAddress ?: user.mailingAddress
				cmd.phone = event.contact?.cellPhone ?: event.contact?.phone2 ?: (user.contactCellPhone ? user.contactCellPhone : user.contactOtherPhone) 
				cmd.useSms = cmd.useSms ?: event.contact ? event.contact.cellPhone != null : user.contactCellPhone != null
				cmd.wizardStep = 'contact'
				break;
			case 'contact':
				cmd.contact = cmd.contact ?: new Contact();
				cmd.contact.properties = cmd.properties
				cmd.contact.mailingAddress = cmd.mailing
				if (cmd.useSms) cmd.contact.cellPhone = cmd.phone
				else cmd.contact.phone2 = cmd.phone
				event.contact = cmd.contact
				event.save()
				
				if (event.hasErrors()) {
					cmd.errors = event.errors
					[cmd:cmd]
					return
				}

				cmd.description = event.description
				cmd.lost = cmd.fmt.format(event.lostTime)
				prepareTracking(cmd, event)
				cmd.wizardStep = 'review'
				break;
			case 'review':
				// TODO: Email Notification
				flash.message='Your Report has been succesfully submitted!  You will be notified when your item is found.'
				redirect (controller: 'index')
				return
				break;
		}
		
		[cmd: cmd]
	}

	private prepareTracking(LostEventCommand cmd, LostEvent event) {
		cmd.trackingId = event.track.collect { it.id }
		cmd.trackingLocation = event.track.collect { it.location }
		cmd.trackingVenue = event.track.collect { it.venue }
		cmd.trackingRoom = event.track.collect { it.room }
	}
	
	def reportPrevious(LostEventCommand cmd) {
		def event = LostEvent.get(cmd.eventId)
		
		switch(cmd.wizardStep) {
			case 'select':
				break;
			case 'confirm':				
				cmd.wizardStep = 'select'
				break;
			case 'trackback':				
				cmd.description = event.description
				cmd.lost = cmd.fmt.format(event.lostTime)
				cmd.location = event.track[0].location
				cmd.venue = event.track[0].venue
				cmd.wizardStep = 'confirm'
				break;
			case 'contact':
				prepareTracking(cmd, event)
				cmd.wizardStep = 'trackback'
				break;
			case 'review':
				cmd.contact = event.contact
				cmd.mailing = event.contact.mailingAddress
				cmd.phone = event.contact.cellPhone ?: event.contact.phone2
				cmd.useSms = event.contact.cellPhone != null
				
				cmd.wizardStep = 'contact'
				break;
		}

		render(view:'report', model:[cmd:cmd])
	}
	
	def listEvents() {
		log.debug("Id's" + params.ids)
		def ids = params.list("ids").collect{ Long.valueOf(it) }
		def items = LostEvent.findAllByIdInList(ids)
		
		[lostItemInstanceList: items]
	}
	
	def delete(Integer id) {
		LostEvent.get(id).delete()
		redirect uri:'/'	
	}

}
